﻿Option Explicit On

Public Class frmAvito
    Private cat As Object
    Private params(0 To 549) As Object
    Private is_run As Boolean
    Private Const SITE_URL As String = "http://m.avito.ru/"
    Private adverts() As AdvertType
    Private cur_adv As Integer
    Public Const ADV_NAME As String = "avito"
    Public file_name As String
    Public catalog_name As String
    Private h1 As String
    Private wbc As New System.Net.WebClient



    Private Sub frmAvito_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        cat = {{"komnaty", 200, 511}, {"kvartiry", 201, 549}}

        params(200) = { _
            {"Продам", "prodam"}, _
            {"Куплю", "1053"}, _
            {"Сдам", "1055"}, _
            {"Сниму", "1056"}}
        params(511) = {}

        params(201) = { _
            {"Продам", "prodam"}, _
            {"Куплю", "1058"}, _
            {"Сдам", "1060"}, _
            {"Сниму", "1061"}}
        params(549) = { _
            {"Студии", "/studii", "AVITO-Студии", "1"}, _
            {"1-комнатные", "/1-komnatnye", "AVITO-", "1"}, _
            {"2-комнатные", "/2-komnatnye", "AVITO-", "2"}, _
            {"3-комнатные", "/3-komnatnye", "AVITO-", "3"}, _
            {"4-комнатные", "/4-komnatnye", "AVITO-", "4"}, _
            {"5-комнатные", "/5-komnatnye", "AVITO-", "5"}, _
            {"более 5 комнат", "/mnogokomnatnye", "", "6"}}

        cboCatalog.SelectedIndex = 0

        lstConsole.Dock = DockStyle.Fill
        'web.Visible = False
        wbc.Encoding = System.Text.Encoding.UTF8
    End Sub



    Private Sub cboCatalog_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cboCatalog.SelectedIndexChanged
        Dim n As Integer, c As Integer
        cboType.Items.Clear()
        c = cat(cboCatalog.SelectedIndex, 1)
        For n = 0 To UBound(params(c))
            cboType.Items.Add(params(c)(n, 0))
        Next
        cboType.SelectedIndex = 0

        cboKomnat.Items.Clear()
        cboKomnat.Items.Add("Все")
        c = cat(cboCatalog.SelectedIndex, 2)
        For n = 0 To UBound(params(c))
            cboKomnat.Items.Add(params(c)(n, 0))
        Next
        cboKomnat.SelectedIndex = 0
    End Sub



    Private Sub btnRun_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnRun.Click
        Dim params_txt As String
        Dim url As String, catalog As String
        Dim response As String
        Dim match As Match
        Dim p As Integer

        btnRun.Enabled = False

        'Подготавливаем URL
        p = cboCatalog.SelectedIndex
        catalog = cat(p, 0)

        params_txt = params(cat(p, 1))(cboType.SelectedIndex, 1)
        If cboKomnat.SelectedIndex > 0 Then
            'params_txt = params_txt & "." & cat(p, 2) & "_"
            params_txt = params_txt & params(cat(p, 2))(cboKomnat.SelectedIndex - 1, 1)
        End If
        url = SITE_URL & "komsomolsk-na-amure/" & catalog & "/" & params_txt & "?user=1&page="

        'В цикле проходим по всем страницам
        cur_adv = 0
        p = 0
        ReDim adverts(0)
        While True
            p = p + 1
            myConsole(lstConsole, "Загружаем " & p & "-ю страницу")
            Application.DoEvents()

            'Получаем текущую страницу
            Try : response = wbc.DownloadString(url & p)
            Catch ex As Net.WebException
                If ex.Status = Net.WebExceptionStatus.ProtocolError Then
                    If CType(ex.Response, Net.HttpWebResponse).StatusCode = Net.HttpStatusCode.NotFound Then
                        myConsole(lstConsole, "Раздел пустой.")
                        Exit Sub
                    End If
                End If
                myConsole(lstConsole, "Страница не получена. " & ex.Message)
                Beep()
                Exit Sub
            End Try

            'Получаем со страницы все объявления
            Dim tmpS As String
            tmpS = "<h3 class=""item-header.*?<a href=""/(.*?)(\d{7,10})"""
            For Each match In Regex.Matches(response, tmpS, RegexOptions.Singleline)
                ReDim Preserve adverts(cur_adv)
                adverts(cur_adv).url = match.Groups(1).Value & match.Groups(2).Value
                adverts(cur_adv).advid = match.Groups(2).Value
                cur_adv = cur_adv + 1
            Next

            'Ищим ссылку на следующую страницу
            tmpS = "<li class=""page page-next""><a.*page=(\d{1,2})"
            match = Regex.Match(response, tmpS)
            If match.Success = False Then
                Exit While
            End If
        End While

        'Запускаем граббер
        h1 = "AVITO - " & cboCatalog.Text & " " & cboType.Text & " " & cboKomnat.Text
        timTick.Interval = 3000
        timTick.Start()
        cur_adv = 0
        txtCur.Text = 0
        txtMax.Text = adverts.Count
        lstConsole.Items.Add("")

        btnPlayPause.Enabled = True
        is_run = True
    End Sub


    Private Sub btnPlayPause_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnPlayPause.Click
        If is_run = False Then 'Сейчас пауза, нужно запустить
            btnPlayPause.Text = "Приостановить"
            timTick.Interval = 500
            timTick.Start()
        Else 'Сейчас запущено, нужно сделать паузу
            btnPlayPause.Text = "Запустить"
            timTick.Stop()
        End If
        is_run = Not is_run
    End Sub



    Private Sub timTick_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles timTick.Tick
        Dim elem As System.Windows.Forms.HtmlElement
        Dim phone As String
        Dim res As String
        Dim tmpS As String
        Dim trim_chars() As Char = {",", " ", vbCr, vbLf}
        Dim match As Match

        timTick.Stop()
        If is_run = False Then Exit Sub
        txtCur.Text = cur_adv + 1
        myConsole(lstConsole, (cur_adv + 1) & " объявление загружается")

        With adverts(cur_adv)
            '.url = "komsomolsk-na-amure/kvartiry/3-k_kvartira_75_m_34_et._243448337"
            '.advid = "243448337"

            'Проверим если объявление старое, то не загружаем его
            If chkOnlyNew.Checked = True Then
                If DBAdverts_isOldAdvert(ADV_NAME, .advid) = True Then
                    myConsole(lstConsole, "---Это объявление старое")
                    .state = AdvState.old
                    GoTo next_advert
                End If
            End If

get_page:
            'Загружаем страницу
            While True
                web.Navigate(SITE_URL & .url)
                If ReadyStateComplete(web, 30000) = True Then
                    res = web.DocumentText
                    Exit While
                Else
                    myConsole(lstConsole, "---Страница не получена, превышено время ожидания")
                    myConsole(lstConsole, "---Пробуем еще раз")
                End If
            End While

            'Выбираем элемент контейнер телефона
            For Each elem In web.Document.GetElementsByTagName("a")
                If elem.InnerText = "Показать номер" Then
                    Exit For
                End If
            Next

            If elem.InnerText <> "Показать номер" Then
                .phone = {"не указан"}
                myConsole(lstConsole, "---Телефон не указан")
                GoTo skip_phone
            End If

            'В контейнере нажимаем на ссылку
            elem.InvokeMember("click")
            ReadyStateComplete(web, 40000)
            Threading.Thread.Sleep(1000)
            Application.DoEvents()
            'Me.Refresh()
            phone = ""
            For Each elem In web.Document.GetElementsByTagName("a")
                tmpS = elem.GetAttribute("href").Trim()
                If tmpS.StartsWith("tel:") = True Then
                    phone = tmpS.Substring(4, tmpS.Length - 4).Replace("%20", "").Replace("-", "")
                    phone = getBigPhone(phone)
                    Exit For
                End If
            Next
            If phone = "" Then
                myConsole(lstConsole, "---Страница получена не верно. Не найден номер телефона")
                myConsole(lstConsole, "---Загружаем страницу заново")
                GoTo get_page
            End If

            'Получаем номер телефона, ищем его в риэлторах
            .phone = {phone}
            'GoTo skip_phone
            If DBEstate_isEstate(phone, True) = True Then
                myConsole(lstConsole, "---Это риэлтор")
                .state = AdvState.estateInDB
                'Сохраняем объявление с риэлтором как старое
                If DBAdverts_isOldAdvert(ADV_NAME, .advid) = False Then
                    DBAdverts_addOldAdvert(ADV_NAME, .advid)
                End If
                'Переходим к следующему объявлению
                GoTo next_advert
            End If

skip_phone:
            .state = AdvState.normal

            'Ищим адрес
            tmpS = Regex.Match(res, "<span class=""info-text text-user-address"">(.*?)</span>", RegexOptions.Singleline).
                Groups(1).Value.Trim
            .street = GetNormStreet(tmpS, True, {"ул.", "пр.", "пер.", "улица", "проспект", "переулок"})
            .street = .street.Replace("\", "/")
            'номер дома
            With Regex.Match(.street, "([0-9/]+)$")
                If .Success = True Then
                    adverts(cur_adv).street = adverts(cur_adv).street.Substring(0, .Index).Trim()
                    adverts(cur_adv).nomer = .Groups(1).Value
                End If
            End With

            'Описание системы
            tmpS = Regex.Match(res, "<title>(.*)</title>").Groups(1).Value.Trim
            tmpS = Regex.Replace(tmpS, "AVITO.ru &mdash; ", "")
            tmpS = Regex.Replace(tmpS, " в Комсомольске-на-Амуре", "")
            .AddContent(tmpS)
            .AddText(tmpS)
            match = Regex.Match(tmpS, "(\d{1,2})/(\d{1,2}) эт")
            If match.Success = True Then
                .floor = match.Groups(1).Value
                .floor_all = match.Groups(2).Value
            End If

            'Панель или кирпич
            If Regex.IsMatch(res, "кирпичного дома") = True Then
                .AddText("кирпич")
                .building = "к"
            Else
                If Regex.IsMatch(res, "панельного дома") = True Then
                    .AddText("панель")
                    .building = "п"
                End If
            End If

            'Ищем описание клиента
            tmpS = Regex.Match(res, "<section class=""single-item-description"">(.*?)</div>", RegexOptions.Singleline).
                Groups(1).Value.Trim
            tmpS = Regex.Replace(tmpS, "<div.*?>", "")
            tmpS = Regex.Replace(tmpS, "<br />", " ")
            tmpS = tmpS.Trim()
            .AddContent(tmpS)
            .AddText(tmpS)

            'Ищем цену
            tmpS = Regex.Match(res, "<div class=""info-price"">(.*?)</div>", RegexOptions.Singleline).
                Groups(1).Value.Trim().Replace("&nbsp;", "").Replace(" ", "").Replace("руб.", "")
            tmpS = Regex.Replace(tmpS, "<span.*?</span>", "", RegexOptions.Singleline)
            If tmpS = "не указана" Then tmpS = ""
            If Val(tmpS) > 99000 And tmpS.EndsWith("000") Then
                tmpS = tmpS.Substring(0, tmpS.Length - 3)
                .AddText(tmpS & "тыс")
            Else
                .AddText(tmpS)
            End If
            .price = tmpS

next_advert:
            lstConsole.Items.Add("")
            If cur_adv = adverts.Count - 1 Then
                'Объявления кончились, выводим их
                web.Navigate("about:blank")
                ReadyStateComplete(web, 10000)
                Threading.Thread.Sleep(1000)
                web.Visible = True
                web.Left = 0
                web.Dock = DockStyle.Fill
                grbControl.Enabled = False
                lstConsole.Visible = False
                
                'Подготавливаем список перед выводом
                AdvertsCreateList(adverts, chkSaveNew.Checked, ADV_NAME)

                'Собираем HTML код и обновляем WebBrowser
                AdvertsShowList(web, adverts, h1, AddressOf SpanPhoneClick, ADV_NAME)
            Else
                'Смотрим следующее объявление
                If .state = AdvState.old Then 'Если это старая объява, то не ждем
                    timTick.Interval = 100
                Else 'Ждем 3 сек
                    timTick.Interval = 3000
                End If
                timTick.Start()
            End If
        End With
        cur_adv = cur_adv + 1
    End Sub



    Private Sub SpanPhoneClick(ByVal sender As Object, ByVal e As System.EventArgs)
        AdvertsSpanPhoneClick(web, adverts, h1, AddressOf SpanPhoneClick, ADV_NAME)
    End Sub



    Public Function getAdverts() As Object
        Return adverts
    End Function
End Class